package amfphp
{
	import flash.events.EventDispatcher;
	import flash.net.Responder;
	import mx.managers.CursorManager;
	import mx.collections.ArrayCollection;

	public class MySQL extends EventDispatcher
	{
		private var amfphp    :AMFPHP;
		private var responder :Responder;
		
		public function MySQL()
		{
			amfphp    = AMFPHP.getInstance();
			amfphp.addEventListener(AMFPHPEvent.RESULT, propagEvent);
			
			responder = new Responder(onResult, onStatus);
		}
		
		private function propagEvent(e:AMFPHPEvent):void
		{
			dispatchEvent(new AMFPHPEvent(AMFPHPEvent.RESULT, e.result));
		}
		
		// Remote Methodes
		
		public function request(command:Object):void
		{
			CursorManager.setBusyCursor();
			amfphp.call("MySQL.request", responder, command);
			
			trace(command)
		}
		
		// Extends Methodes
		
	
		
		public function del(condition:String, table:String):void
		{
			request("DELETE FROM "+table+" WHERE "+condition);
		}
		
		public function insert(elements:Object, table:String):void
		{
			var command:Array = new Array;
			
			if (elements is Array)
			{
				
				if (elements.length == 0)
				{
					dispatchEvent(new AMFPHPEvent(AMFPHPEvent.RESULT, null));
					return;
				}
				for each (var o:Object in elements)
					command.push(createInsertRequest(o, table));
			}
			else
				command.push(createInsertRequest(elements, table));
			
			request(command);
		}
		
		public function update(elements:Object, table:String, id:String):void
		{
			var command:Array = new Array;
			
			if (elements is Array)
			{
				
				if (elements.length == 0)
				{
					dispatchEvent(new AMFPHPEvent(AMFPHPEvent.RESULT, null));
					return;
				}
				for each (var o:Object in elements)
					command.push(createUpdateRequest(o, table, id));
			}
			else
				command.push(createUpdateRequest(elements, table, id));
			request(command);
		}
		
		// Utils
		
		private function createInsertRequest(elements:Object, table:String):String
		{
			
			var varName  :Array = new Array;
			var varValue :Array = new Array;
			for (var o:Object in elements)
			{
				var name  :String = String(o);
				var value :String = String(elements[o]);
				if (name!='mx_internal_uid')
				{
					varName.push(name);
					varValue.push(sqlProtect(value));
				}
			}
			
			return "INSERT INTO "+table+" (`"+varName.join("`, `")+"`) VALUES ('"+varValue.join("', '")+"');";
		}
		
		private function createUpdateRequest(elements:Object, table:String, id:String):String
		{
			
			var varUp  :Array = new Array;
			for (var o:Object in elements)
			{
				var name  :String = String(o);
				var value :String = String(elements[o]);
				if (name!='mx_internal_uid')
					varUp.push("`"+name+"`='"+sqlProtect(value)+"'");
			}
			
			return "UPDATE "+table+" SET "+varUp.join(", ")+" WHERE `"+id+"`='"+elements[id]+"'";
		}
		
		private function sqlProtect(str:String):String
		{
			return str.replace(/\\/g, "\\\\").replace(/\'/g, "\\'");
		}
		
		private function copy(input:Object):Array
		{
			var output:Array = new Array;
			for (var o:Object in input)
				output[o] = input[o];
			return output;
		}
		
		// Events
		
		
		private function onResult(result:Object):void
		{
			CursorManager.removeBusyCursor();
			dispatchEvent(new AMFPHPEvent(AMFPHPEvent.RESULT, result));
		}
		
		
		private function onStatus(status:Object):void
		{
			CursorManager.removeBusyCursor();
			throw new Error('\r'+status.code+' ('+status.level+')\r'+status.description+'\ron '+status.details+' (line '+status.line+')');
		}
	}
}
